home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-07-03 | 9.0 KB | 378 lines | [TEXT/MMCC] |
-
- // * This is ResAnomaly. Based on FrDropApp
- // * ©1995 Chris K. Thomas. ©1994 Metrowerks Inc. All Rights Reserved.
-
-
- /*
- ckt July the Second 1995
-
- Grab text resources up front to support the current architecture of
- ResAnomaly. Eventually, I think we're going to go to three stages:
-
- …resource file is open
- Stage One: Data retrieval. Gather all the named resources
- in the file into a list.
- …resource file is closed
-
- Stage Two: Analysis. Check to be sure
- there aren't duplicate names & other stuff
-
- Stage Three: Emitter. Write the data in the proper format
- to the output stream.
-
- Currently, we only effectively have a mixed version of stages 1 & 3,
- and the resource file is open throughout, which makes it difficult
- to get to our own resources without abusing the Resource Mangler.
- */
-
- #define DEBUG_ME Yes, Please
-
- #if (defined DEBUG_ME) && (defined __powerc)
- #pragma traceback on
- #endif
-
- // ————• Us
- #include "FrDropApp.h"
- #include "ResAnomaly Settings.h"
-
- // ————• PP
- #include <UException.h>
- #include <LModelDirector.h>
- #include <LFileStream.h>
- #include <UAppleEventsMgr.h>
- #include <LHandleStream.h>
- #include <UMemoryMgr.h>
-
- // ————• my less annoying (to the programmer) standard file replacement
- #include "StFile.h"
-
- const ResIDT ALRT_NoFiles = 200;
-
- static void InsertTextIntoStream(Handle inOurResource, LStream &inStream);
- static void InsertTextIntoStream(short inID, LStream &inStream);
- static void AddDotExtension(Str255 ioString, const Str255 inDot);
- static void MapToValidC(Str255 ioString);
-
-
- // ===========================================================================
- // • Main Program
- // ===========================================================================
-
- void main(void)
- {
- try
- {
- FrDropApp gApp;
- gApp.Run();
- }
- catch(...)
- {
-
- }
- }
-
-
- // ===========================================================================
- // • FrDropApp Class
- // ===========================================================================
-
- FrDropApp::FrDropApp()
- {
- MaxApplZone();
-
- InitGraf((Ptr) &qd.thePort); // Toolbox Managers
- InitFonts();
- InitWindows();
- InitMenus();
- TEInit();
- InitDialogs(nil);
-
- new LModelDirector(this); // AppleEvent Handlers
-
- mRunning = true;
-
- // * preload our text, because we can't access
- // * our res file during processing
-
- mTextBeginLine = Get1Resource('TEXT', 128);
- mTextIDequals = Get1Resource('TEXT', 130);
- mTextIDend = Get1Resource('TEXT', 131);
- mOutputHeaderStart = Get1Resource('TEXT', 256);
- mOutputHeaderStop = Get1Resource('TEXT', 257);
-
- ThrowIfNULL_(mTextBeginLine);
- ThrowIfNULL_(mTextIDequals);
- ThrowIfNULL_(mTextIDend);
- ThrowIfNULL_(mOutputHeaderStart);
- ThrowIfNULL_(mOutputHeaderStop);
- }
-
-
- void
- FrDropApp::Run()
- {
- // This program has no user interface. We only care
- // about AppleEvents.
-
- while (mRunning) {
- EventRecord macEvent;
- if (WaitNextEvent(everyEvent, &macEvent, 2, nil)) {
-
- if (macEvent.what == kHighLevelEvent) {
- AEProcessAppleEvent(&macEvent);
- }
- }
- }
- }
-
-
- void
- FrDropApp::HandleAppleEvent(
- const AppleEvent &inAppleEvent,
- AppleEvent &outAEReply,
- AEDesc &outResult,
- long inAENumber)
- {
- switch (inAENumber) {
-
- case ae_OpenApp:
- StartUp();
- break;
-
- case ae_OpenDoc:
- DoAEOpenDoc(inAppleEvent, outAEReply, inAENumber);
- break;
-
- case ae_Quit:
- DoQuit();
- break;
-
- default:
- LModelObject::HandleAppleEvent(inAppleEvent, outAEReply, outResult, inAENumber);
- break;
- }
- }
-
-
- void
- FrDropApp::StartUp()
- {
- // User double-clicked on the Program's icon
-
- // This program only works when files are dragged on the
- // program's icon in the Finder. So we just display an
- // Alert (which could have instructions for using the program)
- // and then quit.
-
- ::Alert(ALRT_NoFiles, nil);
- DoQuit();
- }
-
-
- void
- FrDropApp::DoAEOpenDoc(
- const AppleEvent &inAppleEvent,
- AppleEvent& /*outAEReply*/,
- long /*inAENumber*/)
- {
- AEDescList docList;
- OSErr err = AEGetParamDesc(&inAppleEvent, keyDirectObject,
- typeWildCard, &docList);
- if (err != noErr) Throw_(err);
-
- Int32 numDocs;
- err = AECountItems(&docList, &numDocs);
- if (err != noErr) Throw_(err);
-
- // Loop through all items in the list
- // Extract descriptor for the document
- // Coerce descriptor data into a FSSpec
- // Tell Program object to open document
-
- for (Int32 i = 1; i <= numDocs; i++) {
- AEKeyword theKey;
- DescType theType;
- FSSpec theFileSpec;
- Size theSize;
- err = AEGetNthPtr(&docList, i, typeFSS, &theKey, &theType,
- (Ptr) &theFileSpec, sizeof(FSSpec), &theSize);
- if (err != noErr) Throw_(err);
- OpenDocument(&theFileSpec);
- }
-
- AEDisposeDesc(&docList);
-
- DoQuit();
- }
-
-
- void
- FrDropApp::OpenDocument(
- FSSpec *inMacFSSpec)
- {
- FSSpec saveSpec = *inMacFSSpec;
- Handle curRes;
- long numTypes;
- long numRes;
- long i, j;
- short currentID;
- ResType currentType;
- Str255 currentName;
- Str255 numString;
- LHandleStream ourStream;
-
- InsertTextIntoStream(mOutputHeaderStart, ourStream);
- ourStream.WriteData(&inMacFSSpec->name[1], inMacFSSpec->name[0]);
- InsertTextIntoStream(mOutputHeaderStop, ourStream);
-
- Try_{
- LFile resFile(*inMacFSSpec);
-
- SetResLoad(false);
- resFile.OpenResourceFork(fsRdPerm);
- SetResLoad(true);
-
- numTypes = Count1Types();
-
- for(i = 1; i <= numTypes; i++)
- {
- Get1IndType(¤tType, i);
- ThrowIfResError_();
-
- numRes = Count1Resources(currentType);
- ThrowIfResError_();
-
- for(j = 1; j <= numRes; j++)
- {
- SetResLoad(false);
- curRes = Get1IndResource(currentType, j);
- SetResLoad(true);
-
- ThrowIfResError_();
- ThrowIfNULL_(curRes);
-
- GetResInfo(curRes, ¤tID, NULL, currentName);
- ThrowIfResError_();
-
- // * if the resource isn't named, how does one identify it?
- if(currentName[0] > 0)
- {
- MapToValidC(currentName); //convert name to C-language usable
-
- // * Write a type string in the format const short kResNameType = 'type';
-
- // InsertTextIntoStream(128, ourStream); // "const kResource"
- // ourStream.WriteData(¤tName[1], currentName[0]); // "<name>"
- // InsertTextIntoStream(129, ourStream); // "Type = '"
- // ourStream.WriteData(¤tType, sizeof(ResType)); // "tnam"
- // InsertTextIntoStream(131, ourStream); // "';\r"
-
- // * Write an ID string in the format const short kResNameID = id#;
- InsertTextIntoStream(mTextBeginLine, ourStream); // "const kResource"
- ourStream.WriteData(¤tName[1], currentName[0]); // "<name>"
- ourStream.WriteData(¤tType, sizeof(ResType)); //tnam
- InsertTextIntoStream(mTextIDequals, ourStream); // "ID = '"
- NumToString(currentID, numString);
- ourStream.WriteData(&numString[1], numString[0]);
- InsertTextIntoStream(mTextIDend, ourStream); // "';\r"
- }
-
- ReleaseResource(curRes);
- }
- }
-
- resFile.CloseResourceFork();
-
- // * we can now safely access our own resources
-
- AddDotExtension(inMacFSSpec->name, kDefaultDotExtension);
-
- StPutFile newFile("\pSave Resource Constants as:", *inMacFSSpec);
-
- if(newFile.reply.sfGood)
- {
- LFile ourFile(newFile.reply.sfFile);
-
- if(newFile.reply.sfReplacing)
- ThrowIfOSErr_(FSpDelete(&newFile.reply.sfFile));
-
- ourFile.CreateNewDataFile(kTextFileCreator, 'TEXT');
-
- StHandleLocker stlock(ourStream.GetDataHandle());
-
- ourFile.OpenDataFork(fsWrPerm);
- ourFile.WriteDataFork(*ourStream.GetDataHandle(), ourStream.GetLength());
- ourFile.CloseDataFork();
- }
- }
- Catch_(inErr)
- {
- Str255 str;
-
- NumToString(inErr,str);
- ParamText(inMacFSSpec->name, str, "\p", "\p");
- CautionAlert(129, NULL);
- } EndCatch_
- }
-
- // * add a .dot extension to a Mac filename (yuk!)
- // * this would make a good alternate constructor argument for
- // * StPutFile.
- void AddDotExtension(Str255 ioString, const Str255 inDot)
- {
- if(ioString[0] >= 32 - inDot[0]) //make space if necessary
- ioString[0] -= inDot[0];
-
- BlockMoveData(&inDot[1], &ioString[ioString[0] + 1], inDot[0]);
- ioString[0] +=inDot[0];
- // * yeah, I know that can be optimized
- }
-
- // * map a string to valid C chars only.
- // * --not very powerful or nice, but needs at
- // * least this level of translation to work properly
- void MapToValidC(Str255 ioString)
- {
- long i;
-
- for(i = 1; i <= ioString[0]; i++)
- {
- if(ioString[i] == ' ' || ioString[i] == '\t') //whitespace
- {
- ioString[i] = '_';
- }
- else if(ioString[i] > 128 || ioString[i] < 0x31)
- {
- ioString[i] = '_';
- }
- }
- }
-
- void InsertTextIntoStream(Handle inOurResource, LStream &inStream)
- {
- ThrowIfNULL_(inOurResource);
-
- HLockHi(inOurResource);
- inStream.WriteData(*inOurResource, GetHandleSize(inOurResource));
- HUnlock(inOurResource);
- }
-
-
- // * insert contents of a 'TEXT' resource into an LStream
- void InsertTextIntoStream(short inID, LStream &inStream)
- {
- Handle ourResource = Get1Resource('TEXT', inID);
-
- InsertTextIntoStream(ourResource, inStream);
-
- // purposely don't dispose text - res manager serves as cache mechanism
- // not an efficient one, to be sure, but it works.
- // * * * can't use this safely when other res forks are open unless
- // * * * guarantee our home currency
- }
-
- void
- FrDropApp::DoQuit()
- {
- mRunning = false;
- }